package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheAdminUser;
import top.lixunda.ecommerce.server.good.api.entity.db.SysGoodCategoryDO;
import top.lixunda.ecommerce.server.good.api.entity.dto.GoodCategoryInsertDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.GoodCategoryUpdateDTO;
import top.lixunda.ecommerce.server.good.mapper.SysGoodCategoryMapper;
import top.lixunda.ecommerce.server.good.service.ISysGoodCategoryService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品类别表，管理员进行维护管理 服务实现类
 * </p>
 *
 * @author Xumda
 * @since 2019-12-18
 */
@Service
public class SysGoodCategoryServiceImpl
        extends BaseServiceImpl<SysGoodCategoryMapper, SysGoodCategoryDO>
        implements ISysGoodCategoryService {

    @Autowired
    public SysGoodCategoryServiceImpl() {
    }

    /**
     * 添加一个商品分类
     *
     * @param goodCategoryInsertDTO 新添加的商品分类数据
     * @return 是否添加成功
     */
    @Override
    public boolean insertGoodCategory(GoodCategoryInsertDTO goodCategoryInsertDTO) {
        if (ObjectValidators.isEmpty(goodCategoryInsertDTO)) {
            throw getAppException("参数不能为空");
        }
        CacheAdminUser cacheAdminUser = currentAdminUserCacheNotNull();
        boolean isRoot = !(goodCategoryInsertDTO.getParentId() != null && goodCategoryInsertDTO.getParentId() > 0);
        SysGoodCategoryDO sysGoodCategoryDO = new SysGoodCategoryDO();
        LocalDateTime localDateTime = LocalDateTime.now();
        sysGoodCategoryDO
                .setIsLeaf(SysGoodCategoryDO.LEAF_IS)
                .setIsRoot(isRoot ? SysGoodCategoryDO.ROOT_IS : SysGoodCategoryDO.ROOT_NOT)
                .setDescription(goodCategoryInsertDTO.getDescription())
                .setName(goodCategoryInsertDTO.getName())
                .setParent(isRoot ? 0 : goodCategoryInsertDTO.getParentId())
                .setCreateTime(localDateTime)
                .setUpdateTime(localDateTime)
                .setCreateUserId(cacheAdminUser.getAccount())
                .setCreateUerName(cacheAdminUser.getName())
                .setUpdateUserId(cacheAdminUser.getAccount())
                .setUpdateUerName(cacheAdminUser.getName())
                .setRemark(goodCategoryInsertDTO.getRemark());
        return this.save(sysGoodCategoryDO);
    }

    /**
     * 更新一个商品分类
     *
     * @param goodCategoryUpdateDTO 需要更新的商品分类数据
     * @return 是否更新成功
     */
    @Override
    public boolean updateGoodCategory(GoodCategoryUpdateDTO goodCategoryUpdateDTO) {
        if (ObjectValidators.isEmpty(goodCategoryUpdateDTO)) {
            throw getAppException("参数不能为空");
        }
        CacheAdminUser cacheAdminUser = currentAdminUserCacheNotNull();
        SysGoodCategoryDO sysGoodCategoryDO = this.getById(goodCategoryUpdateDTO.getId());
        if (ObjectValidators.isEmpty(sysGoodCategoryDO)) {
            throw getAppException("分类信息不存在");
        }
        sysGoodCategoryDO.setName(goodCategoryUpdateDTO.getName())
                .setDescription(goodCategoryUpdateDTO.getDescription())
                .setRemark(goodCategoryUpdateDTO.getRemark())
                .setUpdateTime(LocalDateTime.now())
                .setUpdateUserId(cacheAdminUser.getAccount())
                .setUpdateUerName(cacheAdminUser.getName());
        return this.updateById(sysGoodCategoryDO);
    }

    /**
     * 根据id删除商品分类，只删除该节点，其子节点全部放到父节点中去
     *
     * @param id 商品分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeGoodCategoryById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("商品分类id不能为空");
        }
        currentAdminUserCacheNotNull();
        SysGoodCategoryDO sysGoodCategoryDO = this.getById(id);
        if (ObjectValidators.isEmpty(sysGoodCategoryDO)) {
            throw getAppException("分类信息不存在");
        }
        // 把子节点放到父节点中去
        List<SysGoodCategoryDO> list = this.list(new LambdaQueryWrapper<SysGoodCategoryDO>()
                .eq(SysGoodCategoryDO::getParent, id));
        if (ObjectValidators.isNotEmpty(list)) {
            List<Integer> changeIds = list.stream()
                    .filter(Objects::nonNull)
                    .map(SysGoodCategoryDO::getId)
                    .collect(Collectors.toList());
            if (ObjectValidators.isNotEmpty(changeIds)) {
                this.update(new LambdaUpdateWrapper<SysGoodCategoryDO>()
                        .set(SysGoodCategoryDO::getParent, sysGoodCategoryDO.getParent())
                        .set(SysGoodCategoryDO::getIsRoot, sysGoodCategoryDO.getIsRoot())
                        .in(SysGoodCategoryDO::getId, changeIds));
            }
        }
        // 移除本身节点
        this.removeById(id);
        return true;
    }

    /**
     * 根据id删除商品分类，只删除该节点，其子节点全部放到父节点中去
     *
     * @param ids 商品分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeGoodCategoryByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("商品分类id不能为空");
        }
        for (Integer id : ids) {
            this.removeGoodCategoryById(id);
        }
        return true;
    }

    /**
     * 根据id删除商品分类，删除包括子节点的所有节点
     *
     * @param id 商品分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeGoodCategoryAllById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("商品分类id不能为空");
        }
        currentAdminUserCacheNotNull();
        SysGoodCategoryDO sysGoodCategoryDO = this.getById(id);
        if (ObjectValidators.isEmpty(sysGoodCategoryDO)) {
            throw getAppException("分类信息不存在");
        }
        // 查询所有子节点
        List<SysGoodCategoryDO> list = new ArrayList<>(128);
        list.add(sysGoodCategoryDO);
        List<Integer> selectIds = Collections.singletonList(id);
        List<SysGoodCategoryDO> tempList;
        while (ObjectValidators.isNotEmpty(selectIds)) {
            tempList = this.list(new LambdaQueryWrapper<SysGoodCategoryDO>()
                    .in(SysGoodCategoryDO::getParent, selectIds));
            list.addAll(tempList);
            selectIds = tempList.stream()
                    .map(SysGoodCategoryDO::getId)
                    .collect(Collectors.toList());
        }
        selectIds = list.stream()
                .filter(Objects::nonNull)
                .map(SysGoodCategoryDO::getId)
                .distinct()
                .collect(Collectors.toList());
        if (ObjectValidators.isNotEmpty(selectIds)) {
            this.removeByIds(selectIds);
        }
        return true;
    }

    /**
     * 根据id删除商品分类，删除包括子节点的所有节点
     *
     * @param ids 商品分类id
     * @return 是否删除成功
     */
    @Override
    public boolean removeGoodCategoryAllByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("商品分类id不能为空");
        }
        for (Integer id : ids) {
            this.removeGoodCategoryAllById(id);
        }
        return true;
    }

    /**
     * 根据id查询数据
     *
     * @param id 分类id
     * @return 单条分类数据
     */
    @Override
    public SysGoodCategoryDO queryById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("参数id不能为空");
        }
        return this.getById(String.valueOf(id));
    }

    /**
     * 查询所有分类信息
     *
     * @return 所有分类信息
     */
    @Override
    public List<SysGoodCategoryDO> queryAll() {
        return this.list();
    }

    /**
     * 根据父节点id获取子节点id
     *
     * @param id 父节点id
     * @return 所有子节点列表
     */
    @Override
    public List<SysGoodCategoryDO> queryChildrenByParentId(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("参数id不能为空");
        }
        // id小于等于零时返回根节点列表
        if (id <= 0) {
            return queryRoots();
        }
        return this.list(
                new LambdaQueryWrapper<SysGoodCategoryDO>()
                        .eq(SysGoodCategoryDO::getParent, id));
    }

    /**
     * 查询根节点
     *
     * @return 根节点列表
     */
    @Override
    public List<SysGoodCategoryDO> queryRoots() {
        return this.list(new LambdaQueryWrapper<SysGoodCategoryDO>()
                .eq(SysGoodCategoryDO::getIsRoot, SysGoodCategoryDO.ROOT_IS));
    }
}
